package com.hex.ds.hdrs.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.hex.bigdata.hbda.base.Page;
import com.hex.bigdata.hbda.domain.Dept;
import com.hex.bigdata.hbda.domain.Job;
import com.hex.bigdata.hbda.domain.Role;
import com.hex.bigdata.hbda.domain.User;
import com.hex.bigdata.hbda.service.RoleService;
import com.hex.bigdata.hbda.service.UserService;
import com.hex.bigdata.hbda.service.dto.RoleSmallDto;
import com.hex.bigdata.hbda.service.dto.UserDto;
import com.hex.ds.hdrs.app.dao.AppUserDao;
import com.hex.ds.hdrs.app.dto.AppAdminRelationDto;
import com.hex.ds.hdrs.app.dto.AppUserDto;
import com.hex.ds.hdrs.app.po.AppAdminRelationPo;
import com.hex.ds.hdrs.app.po.AppConf;
import com.hex.ds.hdrs.app.po.MenuPo;
import com.hex.ds.hdrs.app.po.UserConf;
import com.hex.ds.hdrs.app.service.IAppAdminRelationService;
import com.hex.ds.hdrs.app.vo.AppUserVo;
import com.hex.ds.hdrs.common.annotation.AppCodeVerification;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.utils.BaseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AppUserService {
    @Autowired
    private IAppAdminRelationService appAdminRelationService;

    @Autowired
    private UserService userService;

    @Autowired
    private AppUserDao appUserDao;

    @Autowired
    private AppConfService appConfService;

    @Autowired
    private RoleService roleService;

    @AppCodeVerification(paramObject = String.class)
    public List<UserConf> selectAppUser(AppUserVo appUserVo, Page page, String appCode) {
        log.info("【进入了AppUserService的selectAppUser】user={}", appUserVo);
        Map map = BeanUtil.beanToMap(appUserVo);
        return this.appUserDao.qryAppUserList(map, page);
    }

    public List<UserConf> selectAllUser(String appCode) {
        List<UserConf> resultList = new ArrayList<>();
        List<AppAdminRelationPo> adminRelationList = appAdminRelationService.queryList(new AppAdminRelationDto().setAppCode(appCode));
        List<String> appUserCodeList = adminRelationList.stream().map(AppAdminRelationPo::getAdminUserCode).collect(Collectors.toList());
        List<UserConf> userList = appUserDao.selectAllUser();
        for (UserConf user : userList) {
            if (!appUserCodeList.contains(user.getUsername())) {
                resultList.add(user);
            }
        }
        return resultList;
    }

    public void add(AppUserDto userDto) {
        log.info("【进入了AppUserService的add】【{}】", userDto);
        if ("1".equals(userDto.getDataType())) {
            this.createUser(userDto);
        } else {
            this.updateUser(userDto.getUsername(), userDto.getRoles());
        }
        this.appAdminRelationService.addAppUser(userDto, userDto.getAppCode());
    }

    public void appEdit(AppUserDto userDto) {
        log.info("进入【AppUserService.appEdit】【{}】", userDto);
        this.updateUser(userDto);
        this.appAdminRelationService.addAppUser(userDto, userDto.getAppCode());
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void delete(List<String> usernameList, String appCode) {
        log.info("进入【AppUserService.delete】，参数:{}, {}", usernameList, appCode);
        for (String username : usernameList) {
            this.appAdminRelationService.remove(appCode, username);
        }
    }

    /*
     * @Method: getCrunUserAppPermission <br>
     * @Param: [appCode] <br>
     * @Return: java.util.List<java.lang.String> <br>
     * @Description：获取当前用户在指定应用中的权限标识<br>
     * @Author： wz.li<br>
     * @Date： 2023/6/1 13:54 <br>
     * @Version： V2.0.2<br>
     */
    public List<MenuPo> getCrunUserAppPermission(String appCode) {
        AppConf appConf = appConfService.qryAppConfByAppCode(appCode);
        if (appConf.getAppAdmin().equals(BaseUtil.getUserId())) {
            return appAdminRelationService.queryPermissionByRoleId(Const.APP_ADMINS_ROLE_ID);
        }
        Set<MenuPo> permissionSet = new HashSet<>();
        List<AppAdminRelationPo> adminRelationList = appAdminRelationService.queryList(BaseUtil.getUserId(), appCode);
        for (AppAdminRelationPo relation : adminRelationList) {
            if (Const.DEV_ADMINS_TYPE.equals(relation.getAdminType())) {
                permissionSet.addAll(appAdminRelationService.queryPermissionByRoleId(Const.DEV_ADMINS_ROLE_ID));
            }
            if (Const.MONITOR_ADMINS_TYPE.equals(relation.getAdminType())) {
                permissionSet.addAll(appAdminRelationService.queryPermissionByRoleId(Const.MONITOR_ADMINS_ROLE_ID));
            }
            if (Const.RELEASE_ADMINS_TYPE.equals(relation.getAdminType())) {
                permissionSet.addAll(appAdminRelationService.queryPermissionByRoleId(Const.RELEASE_ADMINS_ROLE_ID));
            }
        }
        return permissionSet.stream().collect(Collectors.toList());
    }

    public List<Long> getAppUserRole(String username, String appCode) {
        List<Long> roleIdList = new ArrayList<>();
        List<AppAdminRelationPo> adminRelationList = appAdminRelationService.queryList(username, appCode);
        for (AppAdminRelationPo relation : adminRelationList) {
            if (Const.DEV_ADMINS_TYPE.equals(relation.getAdminType())) {
                roleIdList.add(Long.valueOf(Const.DEV_ADMINS_ROLE_ID));
            }
            if (Const.MONITOR_ADMINS_TYPE.equals(relation.getAdminType())) {
                roleIdList.add(Long.valueOf(Const.MONITOR_ADMINS_ROLE_ID));
            }
            if (Const.RELEASE_ADMINS_TYPE.equals(relation.getAdminType())) {
                roleIdList.add(Long.valueOf(Const.RELEASE_ADMINS_ROLE_ID));
            }
        }
        return roleIdList;
    }

    public void updateUser(AppUserDto userDto) {
        User user = new User();
        user.setNickName(userDto.getNickName());
        user.setUsername(userDto.getUsername());
        user.setPhone(userDto.getPhone());
        user.setEmail(userDto.getEmail());
        user.setSex(userDto.getSex());
        user.setEnabled(true);
        user.setId(userDto.getId());
        Set<Role> roles = new HashSet<>();
        for (RoleSmallDto roleSmallDto : userDto.getRoles()) {
            Role role = new Role();
            role.setId(roleSmallDto.getId());
            roles.add(role);
        }
        user.setRoles(roles);
        this.userService.update(user);
    }

    public void updateUser(String username, Set<RoleSmallDto> rolesDto) {
        UserDto userDto = this.userService.findByName(username);

        User user = new User();
        user.setNickName(userDto.getNickName());
        user.setUsername(userDto.getUsername());
        user.setPhone(userDto.getPhone());
        user.setEmail(userDto.getEmail());
        user.setSex(userDto.getSex());
        user.setEnabled(true);
        user.setId(userDto.getId());
        Dept dept = new Dept();
        dept.setId(userDto.getDept().getId());
        dept.setName(userDto.getDept().getName());
        user.setDept(dept);
        Job job = new Job();
        job.setId(userDto.getJob().getId());
        job.setName(userDto.getJob().getName());
        user.setJob(job);
        Set<Role> roles = new HashSet<>();
        rolesDto.addAll(userDto.getRoles());
        for (RoleSmallDto roleSmallDto : rolesDto) {
            if (roleSmallDto != null && roleSmallDto.getId() != null) {
                Role role = new Role();
                role.setId(roleSmallDto.getId());
                roles.add(role);
            }
        }
        user.setRoles(roles);
        this.userService.update(user);
    }

    public void createUser(AppUserDto userDto) {
        User user = new User();
        user.setNickName(userDto.getNickName());
        user.setUsername(userDto.getUsername());
        user.setPhone(userDto.getPhone());
        user.setEmail(userDto.getEmail());
        user.setSex(userDto.getSex());
        user.setEnabled(true);
        user.setPassword(userDto.getPassword());
        Set<Role> roles = new HashSet<>();
        for (RoleSmallDto roleSmallDto : userDto.getRoles()) {
            Role role = new Role();
            role.setId(roleSmallDto.getId());
            roles.add(role);
        }
        Dept dept = new Dept();
        dept.setId(userDto.getDept().getId());
        user.setDept(dept);
        user.setRoles(roles);
        this.userService.create(user);
    }

    public UserDto findUserByUserName(String username) {
        log.info("进入【AppUserService.findUserByUserName】【{}】", username);
        try {
            return this.userService.findByName(username);
        } catch (Exception e) {
            log.error("【findUserByUserName】异常:{}", e.getMessage(), e);
            return null;
        }
    }

    public User findUserById(Long id) {
        log.info("进入【AppUserService.findUserByUserName】【{}】", id);
        Map map = new HashMap();
        map.put("id", id);
        return this.appUserDao.findUserById(map);
    }
}
